package com.christina.engine.intent.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.christina.engine.intent.IntentRecognitionEngine;
import com.christina.engine.intent.model.Intent;
import com.christina.engine.intent.model.IntentContext;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 基于AI的意图识别引擎实现
 * 
 * @author Christina
 */
@Slf4j
@Component
public class AiIntentRecognitionEngine implements IntentRecognitionEngine {

    private final ChatClient chatClient;
    private final ObjectMapper objectMapper;

    public AiIntentRecognitionEngine(ChatClient chatClient, ObjectMapper objectMapper) {
        this.chatClient = chatClient;
        this.objectMapper = objectMapper;
    }

    @Override
    public Intent recognizeIntent(String userInput, IntentContext context) {
        log.info("开始识别用户意图: {}", userInput);
        
        try {
            String prompt = buildIntentRecognitionPrompt(userInput, context);
            String aiResponse = chatClient.prompt(prompt).call().content();
            
            Intent intent = parseIntentFromAiResponse(aiResponse);
            log.info("意图识别完成: {} (置信度: {})", intent.getType(), intent.getConfidence());
            
            return intent;
            
        } catch (Exception e) {
            log.error("意图识别失败", e);
            return buildFallbackIntent(userInput);
        }
    }

    @Override
    public JSONObject extractParameters(String userInput, Intent intent) {
        log.info("提取意图参数: {}", intent.getType());
        
        try {
            String prompt = buildParameterExtractionPrompt(userInput, intent);
            String aiResponse = chatClient.prompt(prompt).call().content();
            
            return parseParametersFromAiResponse(aiResponse, intent);
            
        } catch (Exception e) {
            log.error("参数提取失败", e);
            return new JSONObject();
        }
    }

    @Override
    public double calculateConfidence(String userInput, Intent intent) {
        // 基于多个因素计算置信度
        double baseConfidence = intent.getConfidence();
        
        // 根据输入长度调整
        double lengthFactor = Math.min(1.0, userInput.length() / 50.0);
        
        // 根据关键词匹配调整
        double keywordFactor = calculateKeywordMatchScore(userInput, intent);
        
        return Math.min(1.0, baseConfidence * 0.7 + lengthFactor * 0.15 + keywordFactor * 0.15);
    }

    /**
     * 构建意图识别提示词
     */
    private String buildIntentRecognitionPrompt(String userInput, IntentContext context) {
        StringBuilder prompt = new StringBuilder();
        
        prompt.append("你是一个专业的意图识别专家。请分析用户输入并识别其意图。\n\n");
        
        prompt.append("可能的意图类型：\n");
        for (Intent.IntentType type : Intent.IntentType.values()) {
            prompt.append("- ").append(type.name()).append(": ").append(type.getDescription()).append("\n");
        }
        
        prompt.append("\n用户输入: ").append(userInput).append("\n");
        
        if (context != null) {
            prompt.append("\n上下文信息:\n");
            if (context.getLocation() != null) {
                prompt.append("- 用户位置: ").append(context.getLocation().getCity()).append("\n");
            }
            if (context.getCurrentTime() != null) {
                prompt.append("- 当前时间: ").append(context.getCurrentTime()).append("\n");
            }
        }
        
        prompt.append("\n请以JSON格式返回识别结果：\n");
        prompt.append("{\n");
        prompt.append("  \"intentType\": \"意图类型\",\n");
        prompt.append("  \"confidence\": 0.95,\n");
        prompt.append("  \"reasoning\": \"识别理由\"\n");
        prompt.append("}\n");
        
        return prompt.toString();
    }

    /**
     * 构建参数提取提示词
     */
    private String buildParameterExtractionPrompt(String userInput, Intent intent) {
        StringBuilder prompt = new StringBuilder();
        
        prompt.append("请从用户输入中提取与意图相关的参数。\n\n");
        prompt.append("意图类型: ").append(intent.getType().getDescription()).append("\n");
        prompt.append("用户输入: ").append(userInput).append("\n\n");
        
        switch (intent.getType()) {
            case TRAVEL_PLANNING:
                prompt.append("请提取以下参数（如果存在）：\n");
                prompt.append("- origin: 出发地\n");
                prompt.append("- destination: 目的地\n");
                prompt.append("- departureTime: 出发时间\n");
                prompt.append("- passengerCount: 出行人数\n");
                prompt.append("- budget: 预算\n");
                prompt.append("- transportMode: 交通方式偏好\n");
                break;
            case GENERAL_CHAT:
                prompt.append("请提取以下参数：\n");
                prompt.append("- topic: 聊天主题\n");
                prompt.append("- emotion: 情感倾向\n");
                break;
            default:
                prompt.append("请提取相关的参数信息。\n");
        }
        
        prompt.append("\n请以JSON格式返回参数：\n");
        
        return prompt.toString();
    }

    /**
     * 解析AI响应中的意图
     */
    private Intent parseIntentFromAiResponse(String aiResponse) {
        try {
            // 提取JSON部分
            String jsonPart = extractJsonFromResponse(aiResponse);
            
            // 解析JSON
            Map<String, Object> responseMap = objectMapper.readValue(jsonPart, Map.class);
            
            String intentTypeStr = (String) responseMap.get("intentType");
            double confidence = ((Number) responseMap.get("confidence")).doubleValue();
            String reasoning = (String) responseMap.get("reasoning");
            
            Intent.IntentType intentType;
            try {
                intentType = Intent.IntentType.valueOf(intentTypeStr);
            } catch (IllegalArgumentException e) {
                log.warn("未知意图类型: {}, 使用UNKNOWN", intentTypeStr);
                intentType = Intent.IntentType.UNKNOWN;
            }
            
            return Intent.builder()
                .type(intentType)
                .name(intentType.getDescription())
                .description(reasoning)
                .confidence(confidence)
                .parameters(new JSONObject())
                .build();
                
        } catch (Exception e) {
            log.error("解析AI意图识别响应失败: {}", aiResponse, e);
            throw new RuntimeException("意图识别响应解析失败");
        }
    }

    /**
     * 解析AI响应中的参数
     */
    private JSONObject parseParametersFromAiResponse(String aiResponse, Intent intent) {
        try {
            String jsonPart = extractJsonFromResponse(aiResponse);
            return JSON.parseObject(jsonPart);
        } catch (Exception e) {
            log.error("解析参数失败: {}", aiResponse, e);
            return new JSONObject();
        }
    }

    /**
     * 从响应中提取JSON
     */
    private String extractJsonFromResponse(String response) {
        int startIndex = response.indexOf("{");
        int endIndex = response.lastIndexOf("}");
        
        if (startIndex != -1 && endIndex != -1 && endIndex > startIndex) {
            return response.substring(startIndex, endIndex + 1);
        }
        
        throw new RuntimeException("响应中未找到有效的JSON格式");
    }

    /**
     * 构建兜底意图
     */
    private Intent buildFallbackIntent(String userInput) {
        // 简单的关键词匹配作为兜底
        Intent.IntentType fallbackType = Intent.IntentType.UNKNOWN;
        double confidence = 0.3;
        
        String lowerInput = userInput.toLowerCase();
        
        if (lowerInput.contains("出行") || lowerInput.contains("旅游") || lowerInput.contains("去")) {
            fallbackType = Intent.IntentType.TRAVEL_PLANNING;
            confidence = 0.6;
        } else if (lowerInput.contains("聊天") || lowerInput.contains("你好")) {
            fallbackType = Intent.IntentType.GENERAL_CHAT;
            confidence = 0.7;
        }
        
        return Intent.builder()
            .type(fallbackType)
            .name(fallbackType.getDescription())
            .description("兜底意图识别")
            .confidence(confidence)
            .parameters(new JSONObject())
            .build();
    }

    /**
     * 计算关键词匹配分数
     */
    private double calculateKeywordMatchScore(String userInput, Intent intent) {
        // 简化实现，实际可以使用更复杂的NLP算法
        String lowerInput = userInput.toLowerCase();
        
        switch (intent.getType()) {
            case TRAVEL_PLANNING:
                if (lowerInput.contains("出行") || lowerInput.contains("旅游") || 
                    lowerInput.contains("去") || lowerInput.contains("到")) {
                    return 0.8;
                }
                break;
            case GENERAL_CHAT:
                if (lowerInput.contains("聊天") || lowerInput.contains("你好") || 
                    lowerInput.contains("怎么样")) {
                    return 0.9;
                }
                break;
        }
        
        return 0.5; // 默认分数
    }
}